Skip to content

Method: generatePersistence(Model, GeneratorModel, String)

1: package de.fhdw.wtf.facade;
2:
3: import java.io.IOException;
4: import java.util.Collection;
5: import java.util.concurrent.ExecutionException;
6:
7: import de.fhdw.wtf.common.ast.Model;
8: import de.fhdw.wtf.common.exception.editor.GeneralCheckException;
9: import de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions;
10: import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
11: import de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException;
12: import de.fhdw.wtf.common.task.DependencyTask;
13: import de.fhdw.wtf.common.task.GroupDependencyTask;
14: import de.fhdw.wtf.common.task.TaskExecutorFixed;
15: import de.fhdw.wtf.common.task.result.ExceptionalTaskResult;
16: import de.fhdw.wtf.common.task.result.OKTaskResult;
17: import de.fhdw.wtf.common.task.result.TaskResult;
18: import de.fhdw.wtf.common.task.result.visitor.TaskResultVisitor;
19: import de.fhdw.wtf.generator.database.generation.InitialGenerator;
20: import de.fhdw.wtf.generator.database.tasks.AttributeGenerationTask;
21: import de.fhdw.wtf.generator.database.tasks.SpecializationGenerationTask;
22: import de.fhdw.wtf.generator.database.tasks.TypeGenerationTask;
23: import de.fhdw.wtf.generator.java.generatorModel.GeneratorModel;
24: import de.fhdw.wtf.generator.transformer.clipper.ClipToFileTask;
25: import de.fhdw.wtf.generator.transformer.clipper.ClipperConfiguration;
26: import de.fhdw.wtf.generator.transformer.clipper.LinkToGenClassTask;
27: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.AppStarterTransformer;
28: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.SuperGenerationTransformer;
29: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.ConstructorSymmetricAttribute;
30: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.DelegationTransformer;
31: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.FactoryTransformer;
32: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.InheritanceTransformer;
33: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.OperationAttributeTransformer;
34: import de.fhdw.wtf.generator.transformer.transformers.classTransformer.TypeTransformer;
35: import de.fhdw.wtf.generator.transformer.visitorTransformation.VisitorTypeTransformer;
36: import de.fhdw.wtf.generator.writer.tasks.FileWriterTask;
37: import de.fhdw.wtf.persistence.exception.PersistenceException;
38: import de.fhdw.wtf.persistence.facade.OracleDataBasePreparator;
39: import de.fhdw.wtf.persistence.facade.OracleDatabaseManager;
40: import de.fhdw.wtf.persistence.facade.OracleObjectFacadeImplementation;
41: import de.fhdw.wtf.persistence.utils.PropertiesReaderFile;
42: import de.fhdw.wtf.tooling.SyntaxCheckAbstract;
43:
44: /**
45: * This class provides operations for generating Java-sources and generating the needed database for an AST-Model.
46: */
47: public final class ModelManager extends SyntaxCheckAbstract {
48:         
49:         /**
50:          * The one existing instance of ModelManager.
51:          */
52:         private static ModelManager instance;
53:         
54:         /**
55:          * Provides the one Instance for ModelManager.
56:          *
57:          * @return ModelManager
58:          */
59:         public static synchronized ModelManager getInstance() {
60:                 if (instance == null) {
61:                         instance = new ModelManager();
62:                 }
63:                 return instance;
64:         }
65:         
66:         /**
67:          * Constructs a ModelManager.
68:          */
69:         private ModelManager() {
70:                 
71:         }
72:         
73:         /**
74:          * Generates Java and aspectJ files to the given directory.
75:          *
76:          * @param referencedModel
77:          * model must be referenced successfully before
78:          * @param modelRootDirectory
79:          * Root directory to generate Java sources in.
80:          * @throws MultipleCheckExceptions
81:          * An exception that represents many exceptions that occured while generating.
82:          * @return The produced GeneratorModel.
83:          */
84:         public GeneratorModel generateJava(final Model referencedModel, final String modelRootDirectory)
85:                         throws MultipleCheckExceptions {
86:                 final ClipperConfiguration configurationClip =
87:                                 new ClipperConfiguration(modelRootDirectory + "clipper/generated/model", modelRootDirectory
88:                                                 + "/generated/model");
89:                 final ClipperConfiguration configurationLink =
90:                                 new ClipperConfiguration(modelRootDirectory + "clipper/", modelRootDirectory);
91:                 return this.generateJava(referencedModel, modelRootDirectory, configurationClip, configurationLink, true);
92:         }
93:         
94:         /**
95:          * Generates Java and aspectJ files to the given directory.
96:          *
97:          * @param referencedModel
98:          * model must be referenced successfully before
99:          * @param modelRootDirectory
100:          * Root directory to generate Java sources in. If null, the file writer task is not started.
101:          * @param configurationClip
102:          * The configuration for the ClipToFileTask.
103:          * @param configurationLink
104:          * The configuration for the LinkToGenClassTask.
105:          * @param runVisitorAndFactoryGenerators
106:          * If true, the visitor and factory generators are run.
107:          * @throws MultipleCheckExceptions
108:          * An exception that represents many exceptions that occured while generating.
109:          * @return The produced GeneratorModel.
110:          */
111:         public GeneratorModel generateJava(final Model referencedModel,
112:                         final String modelRootDirectory,
113:                         final ClipperConfiguration configurationClip,
114:                         final ClipperConfiguration configurationLink,
115:                         final boolean runVisitorAndFactoryGenerators) throws MultipleCheckExceptions {
116:                 final MultipleCheckExceptions results = new MultipleCheckExceptions();
117:                 final TaskExecutorFixed exec = TaskExecutorFixed.create();
118:                 final GeneratorModel javaGeneratorModel = GeneratorModel.create();
119:                 
120:                 final GroupDependencyTask transformers = new GroupDependencyTask(exec);
121:                 /* WalkerTasks and WalkerTasks for types */
122:                 try {
123:                         final TypeTransformer typeTransformer = new TypeTransformer(referencedModel, exec, javaGeneratorModel);
124:                         
125:                         final OperationAttributeTransformer operationAttributeTransformer =
126:                                         OperationAttributeTransformer.create(referencedModel, exec, javaGeneratorModel, typeTransformer);
127:                         
128:                         final DelegationTransformer delegationTransformer =
129:                                         new DelegationTransformer(referencedModel, exec, javaGeneratorModel);
130:                         delegationTransformer.addDependency(operationAttributeTransformer);
131:                         
132:                         final SuperGenerationTransformer constructorCallGenerationTask =
133:                                         new SuperGenerationTransformer(referencedModel, exec, javaGeneratorModel);
134:                         
135:                         constructorCallGenerationTask.addDependency(delegationTransformer);
136:                         
137:                         final InheritanceTransformer inheritanceTransformer =
138:                                         new InheritanceTransformer(referencedModel, exec, javaGeneratorModel, operationAttributeTransformer);
139:                         
140:                         final ConstructorSymmetricAttribute constructorSymmetricAttribute =
141:                                         new ConstructorSymmetricAttribute(referencedModel, exec, javaGeneratorModel);
142:                         
143:                         constructorSymmetricAttribute.addDependency(constructorCallGenerationTask);
144:                         constructorSymmetricAttribute.addDependency(operationAttributeTransformer);
145:                         
146:                         transformers.addMembers(
147:                                         typeTransformer,
148:                                         operationAttributeTransformer,
149:                                         constructorCallGenerationTask,
150:                                         inheritanceTransformer);
151:                         
152:                         if (runVisitorAndFactoryGenerators) {
153:                                 final VisitorTypeTransformer typeVisitor =
154:                                                 VisitorTypeTransformer
155:                                                                 .create(referencedModel, exec, javaGeneratorModel, inheritanceTransformer);
156:                                 delegationTransformer.addDependency(typeVisitor);
157:                                 final DependencyTask appStarterTransformer =
158:                                                 new AppStarterTransformer(exec, javaGeneratorModel, inheritanceTransformer);
159:                                 appStarterTransformer.addDependency(typeVisitor);
160:                                 final DependencyTask factoryTransformer =
161:                                                 new FactoryTransformer(exec, javaGeneratorModel, inheritanceTransformer);
162:                                 factoryTransformer.addDependency(appStarterTransformer);
163:                                 
164:                                 // TODO der FinderTransformer muss eventuell eingebunden werden (und
165:                                 // Dependencies hinzugefügt werden)
166:                                 transformers.addMembers(typeVisitor, appStarterTransformer, factoryTransformer);
167:                                 
168:                         }
169:                 } catch (final CyclicPartDefinitionException | CyclicDependencyException e) {
170:                         throw new SystemException(e);
171:                 }
172:                 
173:                 /* Clipper */
174:                 final GroupDependencyTask clipper = new GroupDependencyTask(exec);
175:                 final ClipToFileTask clipperImport = new ClipToFileTask(exec, configurationClip);
176:                 final LinkToGenClassTask methodInsertion =
177:                                 new LinkToGenClassTask(exec, javaGeneratorModel, configurationLink, clipperImport);
178:                 try {
179:                         clipper.addMembers(clipperImport, methodInsertion);
180:                         clipper.addDependency(transformers);
181:                 } catch (final CyclicPartDefinitionException | CyclicDependencyException e) {
182:                         throw new SystemException(e);
183:                 }
184:                 
185:                 if (modelRootDirectory != null) {
186:                         new FileWriterTask(exec, javaGeneratorModel, modelRootDirectory, clipper);
187:                 }
188:                 
189:                 try {
190:                         exec.startAllKnownTasks();
191:                         final Collection<TaskResult> resultTasks = exec.getResultsAndShutdown();
192:                         this.addsExceptionalTasksToMultipleExceptions(results, resultTasks);
193:                         
194:                 } catch (final InterruptedException | ExecutionException e) {
195:                         throw new SystemException(e);
196:                 }
197:                 
198:                 if (!results.isEmpty()) {
199:                         throw results;
200:                 }
201:                 
202:                 return javaGeneratorModel;
203:         }
204:         
205:         /**
206:          * Generates initial persistence and deletes all existing data!
207:          *
208:          * @param model
209:          * The AST-Model to generate persistence for.
210:          * @param genModel
211:          * The Generator model.
212:          * @param dbPropertiesPath
213:          * The path to connection-constants for accessing the database.
214:          * @throws MultipleCheckExceptions
215:          * An exception that represents many exceptions that occured while generating.
216:          */
217:         public void generatePersistence(final Model model, final GeneratorModel genModel, final String dbPropertiesPath)
218:                         throws MultipleCheckExceptions {
219:                 final MultipleCheckExceptions results = new MultipleCheckExceptions();
220:                 try {
221:                         this.prepareDatabase(dbPropertiesPath);
222:                         
223:                         final InitialGenerator generator = new InitialGenerator();
224:                         final TaskExecutorFixed taskManager = TaskExecutorFixed.create();
225:                         
226:                         final TypeGenerationTask typeGenerationTask =
227:                                         new TypeGenerationTask(model, genModel, taskManager, generator);
228:                         final AttributeGenerationTask attributeGenerationTask =
229:                                         new AttributeGenerationTask(model, taskManager, generator);
230:                         final SpecializationGenerationTask specializationGenerationTask =
231:                                         new SpecializationGenerationTask(model, taskManager, generator);
232:                         
233:                         attributeGenerationTask.addDependency(typeGenerationTask);
234:                         specializationGenerationTask.addDependency(typeGenerationTask);
235:                         
236:                         taskManager.startAllKnownTasks();
237:                         
238:                         final Collection<TaskResult> resultTasks = taskManager.getResultsAndShutdown();
239:                         this.addsExceptionalTasksToMultipleExceptions(results, resultTasks);
240:                 } catch (final PersistenceException e) {
241:                         results.add(new GeneralCheckException(e));
242:                 } catch (final InterruptedException | ExecutionException | CyclicDependencyException | IOException e) {
243:                         throw new SystemException(e);
244:                 }
245:•                if (!results.isEmpty()) {
246:                         throw results;
247:                 }
248:                 
249:         }
250:         
251:         /**
252:          * Inspects TaskResults and adds corresponding CheckExceptions to list.
253:          *
254:          * @param list
255:          * A list of exceptions encapsulated as MultipleCheckException.
256:          * @param taskresults
257:          * A collection of the results of executed tasks.
258:          */
259:         private void addsExceptionalTasksToMultipleExceptions(final MultipleCheckExceptions list,
260:                         final Collection<TaskResult> taskresults) {
261:                 for (final TaskResult taskResult : taskresults) {
262:                         taskResult.accept(new TaskResultVisitor() {
263:                                 
264:                                 @Override
265:                                 public void handleOkTaskResult(final OKTaskResult result) {
266:                                         // nothing to do
267:                                 }
268:                                 
269:                                 @Override
270:                                 public void handleExceptionalTaskResult(final ExceptionalTaskResult result) {
271:                                         // TODO get Markable Exceptions
272:                                         list.add(new GeneralCheckException(result.getError()));
273:                                 }
274:                         });
275:                 }
276:         }
277:         
278:         /**
279:          * Trys to prepare the database by generating the meta-structure and procedures.
280:          *
281:          * @param propertiesPath
282:          * Path for a file with connection-constants.
283:          * @throws IOException
284:          * Thrown when the file with connection-constants could not be accessed.
285:          * @throws PersistenceException
286:          * Thrown when some error in the persistence layer occured.
287:          */
288:         private void prepareDatabase(final String propertiesPath) throws IOException, PersistenceException {
289:                 
290:                 final OracleDatabaseManager oracleDatabaseManager = OracleDatabaseManager.getInstance();
291:                 final PropertiesReaderFile prop = new PropertiesReaderFile();
292:                 prop.initialize(propertiesPath);
293:                 oracleDatabaseManager.setConnectionConstantsFromFile(prop);
294:                 oracleDatabaseManager.connect();
295:                 
296:                 final OracleDataBasePreparator preparator = new OracleDataBasePreparator();
297:                 if (!preparator.isTableStructureValid()) {
298:                         preparator.dropWholeSchema();
299:                         preparator.createWholeSchema();
300:                 }
301:                 if (!preparator.areProceduresCreated()) {
302:                         preparator.createProcedures();
303:                 }
304:                 new OracleObjectFacadeImplementation(oracleDatabaseManager, null).clear();
305:                 oracleDatabaseManager.getClassFacade().clear();
306:         }
307: }